package netty.tcp;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.concurrent.GenericFutureListener;


/**
 * @Description TCP
 * @Author 李龙平
 * @Date 2020/10/12 9:59
 */
public class NettyService {

    public static void main(String[] args) throws InterruptedException {

        //创建两个线程组boosGroup workGroup
        //bossGroup只处理连接  和客服端连接处理业务的是workGroup
        //两个都是无限循环
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workGroup = new NioEventLoopGroup();
        //创建服务器的启动端 和参数
        ServerBootstrap bootstrap = new ServerBootstrap();
        try {
            bootstrap.group(bossGroup, workGroup)
                    .channel(NioServerSocketChannel.class)//使用NioServerSocketChannel座位服务器的通道实现
                    .option(ChannelOption.SO_BACKLOG, 128)//设置线程队列的连接个数
                    .childOption(ChannelOption.SO_KEEPALIVE, true)//设置保持活动连接状态
                    .childHandler(new ChannelInitializer<SocketChannel>() { //SocketChannel是netty的包
                        //创建一个通道初始化对象 向pipeline设置处理器
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            // 每个客服端的socketChannel是不同的 可以把每个socketChannel放在一个集合中，与之对应的用户相对应
                            //在推送消息时使用
                            socketChannel.pipeline().addLast(new NettyServerHandler());
                        }
                    });//给workGroup的EventLoop对应的管道设置处理器
            System.out.println("服务器OK");
            //启动服务并且绑定端口 生成一个ChannelFuture对象
            ChannelFuture channelFuture = bootstrap.bind(6668).sync();

            //给channelFuture自测监听器 监控我们关心的事情。
            channelFuture.addListener((GenericFutureListener<ChannelFuture>) future -> {
                if (future.isSuccess()) {
                    System.out.println("监听端口成功");
                } else {
                    System.out.println("监听端口失败");
                }
            });

            //对关闭通道事件进行监听
            channelFuture.channel().closeFuture().sync();
        } finally {
            //关闭客服端
            bossGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        }
    }
}
